﻿using LxBasic;

namespace LxCore
{
    public abstract class VarArrBuilder3
    {
        public abstract class Base
        {
            public Base(double[] x, double[] y, double[] z)
            {
                this.X = x; this.Y = y; this.Z = z;
            }
            public double[] X;
            public double[] Y;
            public double[] Z;
        }
        public class Direct : Base, ICellVarArr<Vector3d>, ICellVarArr<double>, IFaceVarArr<Vector3d>, IFaceVarArr<double>
        {
            public Direct(double[] x, double[] y, double[] z) : base(x, y, z)
            {
            }
            public Vector3d GetCellVar(int cellID)
            {
                return new Vector3d(X[cellID], Y[cellID], Z[cellID]);
            }

            public Vector3d GetFaceVar(int faceID)
            {
                return new Vector3d(X[faceID], Y[faceID], Z[faceID]);
            }

            double ICellVarArr<double>.GetCellVar(int cellID)
            {
                return GetCellVar(cellID).Length();
            }

            double IFaceVarArr<double>.GetFaceVar(int faceID)
            {
                return GetFaceVar(faceID).Length();
            }
        }
        public struct DirectS : ICellVarArr<Vector3d>, ICellVarArr<double>
        {
            public DirectS(double[] u, double[] v, double[] w)
            {
                this.U = u; this.V = v; this.W = w;
            }
            public double[] U;
            public double[] V;
            public double[] W;
            public Vector3d GetCellVar(int cellIdx)
            {
                return new Vector3d(U[cellIdx], V[cellIdx], W[cellIdx]);
            }

            double ICellVarArr<double>.GetCellVar(int cellID)
            {
                return GetCellVar(cellID).Length();
            }
        }
        //public struct DirectFaceVars : IFaceVarArr<Vector3d>, IFaceVarArr<double>
        //{
        //    public DirectFaceVars(double[] u, double[] v, double[] w)
        //    {
        //        this.U = u; this.V = v; this.W = w;
        //    }
        //    public double[] U;
        //    public double[] V;
        //    public double[] W;
        //    public Vector3d GetFaceVar(int faceID)
        //    {
        //        return new Vector3d(U[faceID], V[faceID], W[faceID]);
        //    }

        //    double IFaceVarArr<double>.GetFaceVar(int faceID)
        //    {
        //        return GetFaceVar(faceID).Length();
        //    }
        //}
        public class InnFaceAve :Base, IFaceVarArr<Vector3d>, IFaceVarArr<double>
        {
            public InnFaceAve(FvZone zone, double[] x, double[] y, double[] z):base(x,y,z)
            {
                this.innFaces = zone.InnFaces;
            }
            private FvInnFace[] innFaces;
            public Vector3d GetFaceVar(int faceID)
            {
                ref FvInnFace f = ref innFaces[faceID];
                return (1 - f.gOwner) * new Vector3d(X[f.OSideCell], Y[f.OSideCell], Z[f.OSideCell])
                    + f.gOwner * new Vector3d(X[f.NSideCell], Y[f.NSideCell], Z[f.NSideCell]);
            }

            double IFaceVarArr<double>.GetFaceVar(int faceID)
            {
                return GetFaceVar(faceID).Length();
            }
        }
    }
}
